package com.wjv.example.spbt.task.service;

import org.springframework.stereotype.Service;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * <p>Title: TaskService</p>
 *
 * @author zmj
 * @since 2022/2/7 11:13
 */
@Service
public class TaskService {

    /**
     * 串行方式执行
     */
    public ResultVO task() throws InterruptedException {
        DataParams params = new DataParams();
        // 步骤 1
        DataDTO dto1 = step1(params);
        // 步骤 2
        DataDTO dto2 = step2(params);
        // 步骤 3
        DataDTO dto3 = step3(params);
        // 步骤 4
        DataDTO dtoN = stepN(params);
        // 处理数据并返回结果
        return doProcess(dto1, dto2, dto3, dtoN);
    }

    /**
     * 并行执行
     */
    public ResultVO parallelTask() throws InterruptedException, ExecutionException {
        DataParams params = new DataParams();
        CountDownLatch countDownLatch = new CountDownLatch(4);

        // 步骤 1
        Future<DataDTO> dto1 = MyThreadPool.submitTask(() -> {
            try {
                return step1(params);
            } finally {
                countDownLatch.countDown();
            }
        });

        // 步骤 2
        Future<DataDTO> dto2 = MyThreadPool.submitTask(() -> {
            try {
                return step2(params);
            } finally {
                countDownLatch.countDown();
            }
        });

        // 步骤 3
        Future<DataDTO> dto3 = MyThreadPool.submitTask(() -> {
            try {
                return step3(params);
            } finally {
                countDownLatch.countDown();
            }
        });
        // 步骤 4
        Future<DataDTO> dtoN = MyThreadPool.submitTask(() -> {
            try {
                return stepN(params);
            } finally {
                countDownLatch.countDown();
            }
        });
        // 阻塞，等待子任务执行完成后发行
        countDownLatch.await();
        // 处理数据并返回结果
        return doProcess(dto1.get(), dto2.get(), dto3.get(), dtoN.get());
    }


    public DataDTO step1(DataParams params) throws InterruptedException {
        Thread.sleep(200);
        return new DataDTO();
    }

    public DataDTO step2(DataParams params) throws InterruptedException {
        Thread.sleep(200);
        return new DataDTO();
    }

    public DataDTO step3(DataParams params) throws InterruptedException {
        Thread.sleep(200);
        return new DataDTO();
    }

    public DataDTO stepN(DataParams params) throws InterruptedException {
        Thread.sleep(200);
        return new DataDTO();
    }

    public ResultVO doProcess(DataDTO... dto) {
        return new ResultVO("执行成功");
    }
}
